<template>
  <div class="job-container">
    <a-card class="header-card">
      <div class="header-content">
        <div class="header-text">
          <h1 class="title">定时任务管理</h1>
          <p class="subtitle">管理系统中所有定时任务的执行状态、调度配置和监控</p>
        </div>
        <div class="header-actions">
          <a-space>
            <a-button type="primary" @click="handleQuery" class="refresh-btn">
              <template #icon><sync-outlined /></template>
              刷新任务
            </a-button>
            <a-button type="primary" @click="handleAdd" class="add-btn">
              <template #icon><plus-outlined /></template>
              新增任务
            </a-button>
          </a-space>
        </div>
      </div>
    </a-card>

    <a-card class="stats-card">
      <a-row :gutter="16">
        <a-col :span="6">
          <a-statistic title="任务总数" :value="jobs.length" class="stat-item">
            <template #prefix><schedule-outlined /></template>
          </a-statistic>
        </a-col>
        <a-col :span="6">
          <a-statistic title="运行中" :value="runningCount" class="stat-item running">
            <template #prefix><play-circle-outlined /></template>
          </a-statistic>
        </a-col>
        <a-col :span="6">
          <a-statistic title="已暂停" :value="pausedCount" class="stat-item paused">
            <template #prefix><pause-circle-outlined /></template>
          </a-statistic>
        </a-col>
        <a-col :span="6">
          <a-statistic title="错误状态" :value="errorCount" class="stat-item error">
            <template #prefix><exclamation-circle-outlined /></template>
          </a-statistic>
        </a-col>
      </a-row>
    </a-card>

    <a-card class="table-card">
      <a-table
          :dataSource="jobs"
          :columns="columns"
          :loading="loading"
          :pagination="false"
          rowKey="name"
          bordered
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'state'">
            <a-tag :color="getStateColor(record.state)">
              {{ record.state }}
            </a-tag>
          </template>

          <template v-else-if="column.dataIndex === 'operation'">
            <a-space class="operation-buttons">
              <a-popconfirm
                  title="手动执行会立即执行一次，确定执行？"
                  ok-text="是"
                  cancel-text="否"
                  @confirm="handleRun(record)"
              >
                <a-button type="primary" size="small">
                  手动执行
                </a-button>
              </a-popconfirm>
              <a-tooltip title="重启任务">
                <a-popconfirm
                    title="确定重启此任务？"
                    ok-text="确认"
                    cancel-text="取消"
                    @confirm="handleResume(record)"
                >
                  <a-button
                      v-show="record.state === 'PAUSED' || record.state === 'ERROR'"
                      type="primary"
                      shape="circle"
                      class="action-btn resume-btn"
                  >
                    <template #icon><redo-outlined /></template>
                  </a-button>
                </a-popconfirm>
              </a-tooltip>

              <a-tooltip title="暂停任务">
                <a-popconfirm
                    title="确定暂停此任务？"
                    ok-text="确认"
                    cancel-text="取消"
                    @confirm="handlePause(record)"
                >
                  <a-button
                      v-show="record.state === 'NORMAL' || record.state === 'BLOCKED'"
                      type="primary"
                      shape="circle"
                      class="action-btn pause-btn"
                  >
                    <template #icon><pause-outlined /></template>
                  </a-button>
                </a-popconfirm>
              </a-tooltip>

              <a-tooltip title="编辑任务">
                <a-button
                    type="primary"
                    shape="circle"
                    class="action-btn edit-btn"
                    @click="handleEdit(record)"
                >
                  <template #icon><edit-outlined /></template>
                </a-button>
              </a-tooltip>

              <a-tooltip title="删除任务">
                <a-popconfirm
                    title="删除后不可恢复，确认删除?"
                    ok-text="确认"
                    cancel-text="取消"
                    @confirm="handleDelete(record)"
                >
                  <a-button type="primary" shape="circle" danger class="action-btn">
                    <template #icon><delete-outlined /></template>
                  </a-button>
                </a-popconfirm>
              </a-tooltip>
            </a-space>
          </template>
        </template>
      </a-table>
    </a-card>

    <!-- 任务编辑/新增模态框 -->
    <a-modal
        :title="job.id ? '编辑定时任务' : '新增定时任务'"
        v-model:visible="modalVisible"
        :confirm-loading="modalLoading"
        @ok="handleModalOk"
        :width="700"
        centered
        class="job-modal"
    >
      <a-form :model="job" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
        <a-form-item label="任务类名" required>
          <a-input v-model:value="job.name" placeholder="请输入任务类全限定名">
            <template #prefix><code-outlined /></template>
          </a-input>
        </a-form-item>

        <a-form-item label="任务描述">
          <a-input v-model:value="job.description" placeholder="请输入任务描述">
            <template #prefix><file-text-outlined /></template>
          </a-input>
        </a-form-item>

        <a-form-item label="任务分组" required>
          <a-input v-model:value="job.group" :disabled="!!job.state" placeholder="请输入任务分组">
            <template #prefix><team-outlined /></template>
          </a-input>
        </a-form-item>

        <a-form-item label="Cron表达式" required>
          <a-input v-model:value="job.cronExpression" placeholder="请输入Cron表达式">
            <template #prefix><clock-circle-outlined /></template>
          </a-input>

          <div class="cron-tips">
            <a-alert message="Cron表达式示例" type="info" show-icon>
              <template #description>
                <div class="cron-examples">
                  <div><a-tag color="blue">0/5 * * * * ?</a-tag> 每5秒执行一次</div>
                  <div><a-tag color="blue">0 0/5 * * * ?</a-tag> 每5分钟执行一次</div>
                  <div><a-tag color="blue">0 0 12 * * ?</a-tag> 每天中午12点执行</div>
                  <div><a-tag color="blue">0 15 10 ? * MON-FRI</a-tag> 周一至周五每天上午10:15执行</div>
                </div>
              </template>
            </a-alert>
          </div>
        </a-form-item>
      </a-form>

      <template #footer>
        <a-button @click="modalVisible = false">取消</a-button>
        <a-button type="primary" @click="handleModalOk" :loading="modalLoading">保存任务</a-button>
      </template>
    </a-modal>
  </div>
</template>

<script>
import { defineComponent, onMounted, ref, computed } from 'vue';
import axios from 'axios';
import { notification } from 'ant-design-vue';
import {
  SyncOutlined, PlusOutlined, ScheduleOutlined,
  PlayCircleOutlined, PauseCircleOutlined, ExclamationCircleOutlined,
  RedoOutlined, PauseOutlined, EditOutlined, DeleteOutlined,
  CodeOutlined, FileTextOutlined, TeamOutlined, ClockCircleOutlined
} from '@ant-design/icons-vue';

export default defineComponent({
  name: 'batch-job-view',
  components: {
    SyncOutlined,
    PlusOutlined,
    ScheduleOutlined,
    PlayCircleOutlined,
    PauseCircleOutlined,
    ExclamationCircleOutlined,
    RedoOutlined,
    PauseOutlined,
    EditOutlined,
    DeleteOutlined,
    CodeOutlined,
    FileTextOutlined,
    TeamOutlined,
    ClockCircleOutlined
  },
  setup () {
    const jobs = ref([]);
    const loading = ref(false);

    const columns = [{
      title: '任务分组',
      dataIndex: 'group',
      width: '15%'
    }, {
      title: '类名',
      dataIndex: 'name',
      width: '20%'
    }, {
      title: '描述',
      dataIndex: 'description',
      width: '20%'
    }, {
      title: '状态',
      dataIndex: 'state',
      width: '10%'
    }, {
      title: 'Cron表达式',
      dataIndex: 'cronExpression',
      width: '15%'
    }, {
      title: '下次执行时间',
      dataIndex: 'nextFireTime',
      width: '10%'
    }, {
      title: '操作',
      dataIndex: 'operation',
      width: '10%',
      align: 'center'
    }];

    // 计算不同状态的任务数量
    const runningCount = computed(() => {
      return jobs.value.filter(j => j.state === 'NORMAL' || j.state === 'BLOCKED').length;
    });

    const pausedCount = computed(() => {
      return jobs.value.filter(j => j.state === 'PAUSED').length;
    });

    const errorCount = computed(() => {
      return jobs.value.filter(j => j.state === 'ERROR').length;
    });

    // 根据状态获取标签颜色
    const getStateColor = (state) => {
      switch(state) {
        case 'NORMAL':
        case 'BLOCKED':
          return 'green';
        case 'PAUSED':
          return 'orange';
        case 'ERROR':
          return 'red';
        default:
          return 'blue';
      }
    };

    const handleQuery = () => {
      loading.value = true;
      jobs.value = [];
      axios.get('/batch/admin/job/query').then((response) => {
        loading.value = false;
        const data = response.data;
        if (data.success) {
          jobs.value = data.content;
        } else {
          notification.error({description: data.message});
        }
      }).catch(() => {
        loading.value = false;
      });
    };

    // -------- 表单 ---------
    const job = ref({});
    const modalVisible = ref(false);
    const modalLoading = ref(false);
    const handleModalOk = () => {
      modalLoading.value = true;
      let url = "add";
      if (job.value.state) {
        url = "reschedule";
      }
      axios.post('/batch/admin/job/' + url, job.value).then((response) => {
        modalLoading.value = false;
        const data = response.data;
        if (data.success) {
          modalVisible.value = false;
          notification.success({description: "保存成功！"});
          handleQuery();
        } else {
          notification.error({description: data.message});
        }
      });
    };

    /**
     * 新增
     */
    const handleAdd = () => {
      modalVisible.value = true;
      job.value = {
        group: 'DEFAULT'
      };
    };

    /**
     * 编辑
     */
    const handleEdit = (record) => {
      modalVisible.value = true;
      job.value = window.Tool.copy(record);
    };

    /**
     * 删除
     */
    const handleDelete = (record) => {
      axios.post('/batch/admin/job/delete', {
        name: record.name,
        group: record.group
      }).then((response) => {
        const data = response.data;
        if (data.success) {
          notification.success({description: "删除成功！"});
          handleQuery();
        } else {
          notification.error({description: data.message});
        }
      });
    };

    /**
     * 暂停
     */
    const handlePause = (record) => {
      axios.post('/batch/admin/job/pause', {
        name: record.name,
        group: record.group
      }).then((response) => {
        const data = response.data;
        if (data.success) {
          notification.success({description: "暂停成功！"});
          handleQuery();
        } else {
          notification.error({description: data.message});
        }
      });
    };
    /**
     * 手动执行
     */
    const handleRun = (record) => {
      axios.post('/batch/admin/job/run', record).then((response) => {
        const data = response.data;
        if (data.success) {
          notification.success({description: "手动执行成功！"});
        } else {
          notification.error({description: data.message});
        }
      });
    };
    /**
     * 重启
     */
    const handleResume = (record) => {
      axios.post('/batch/admin/job/reschedule', record).then((response) => {
        modalLoading.value = false;
        const data = response.data;
        if (data.success) {
          notification.success({description: "重启成功！"});
          handleQuery();
        } else {
          notification.error({description: data.message});
        }
      });
    };

    onMounted(() => {
      handleQuery();
    });

    return {
      columns,
      jobs,
      loading,
      handleQuery,
      handleAdd,
      handleEdit,
      handleDelete,
      handleResume,
      handlePause,
      job,
      modalVisible,
      modalLoading,
      handleModalOk,
      runningCount,
      pausedCount,
      errorCount,
      getStateColor,
      handleRun
    };
  }
})
</script>

<style scoped>
.job-container {
  max-width: 1400px;
  margin: 0 auto;
  padding: 20px;
}

.header-card {
  border-radius: 10px;
  margin-bottom: 20px;
  background: linear-gradient(135deg, #1890ff 0%, #722ed1 100%);
  color: white;
  overflow: hidden;
}

.header-card :deep(.ant-card-body) {
  padding: 0;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px;
}

.header-text .title {
  font-size: 24px;
  font-weight: 600;
  margin-bottom: 8px;
  color: white;
}

.header-text .subtitle {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.85);
}

.refresh-btn {
  background: rgba(255, 255, 255, 0.2);
  border-color: transparent;
}

.add-btn {
  background: #13c2c2;
  border-color: transparent;
}

.stats-card {
  border-radius: 10px;
  margin-bottom: 20px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}

.stat-item {
  text-align: center;
  padding: 12px;
  border-radius: 8px;
  background: #f8f9fa;
}

.stat-item :deep(.ant-statistic-title) {
  font-size: 16px;
  font-weight: 500;
}

.stat-item :deep(.ant-statistic-content) {
  font-size: 24px;
  font-weight: 600;
}

.stat-item.running :deep(.ant-statistic-content) {
  color: #52c41a;
}

.stat-item.paused :deep(.ant-statistic-content) {
  color: #faad14;
}

.stat-item.error :deep(.ant-statistic-content) {
  color: #f5222d;
}

.table-card {
  border-radius: 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  overflow: hidden;
}

.operation-buttons {
  display: flex;
  justify-content: center;
}

.action-btn {
  display: flex;
  align-items: center;
  justify-content: center;
}

.resume-btn {
  background: #52c41a;
  border-color: #52c41a;
}

.pause-btn {
  background: #faad14;
  border-color: #faad14;
}

.edit-btn {
  background: #1890ff;
  border-color: #1890ff;
}

.cron-tips {
  margin-top: 12px;
}

.cron-examples {
  margin-top: 10px;
}

.cron-examples > div {
  margin-bottom: 8px;
  display: flex;
  align-items: center;
}

.cron-examples .ant-tag {
  margin-right: 8px;
}

.job-modal :deep(.ant-modal-header) {
  border-radius: 10px 10px 0 0;
}

.job-modal :deep(.ant-modal-body) {
  padding: 24px;
}

.job-modal :deep(.ant-form-item) {
  margin-bottom: 20px;
}

@media (max-width: 768px) {
  .header-content {
    flex-direction: column;
    align-items: flex-start;
  }

  .header-actions {
    margin-top: 16px;
    width: 100%;
  }

  .stats-card .ant-col {
    margin-bottom: 16px;
  }
}
</style>